package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.JwtClaimsConstant;
import com.sky.constant.*;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.EmployeePageQueryDTO;
import com.sky.dto.PasswordEditDTO;
import com.sky.entity.Employee;
import com.sky.exception.BaseException;
import com.sky.exception.*;
import com.sky.mapper.EmployeeMapper;
import com.sky.properties.JwtProperties;
import com.sky.result.PageBean;
import com.sky.service.EmployeeService;
import com.sky.utils.JwtUtil;
import com.sky.vo.employee.EmployeeLoginVO;
import com.sky.vo.employee.EmployeeVO;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@AllArgsConstructor
public class EmployeeServiceImpl implements EmployeeService {

    private EmployeeMapper employeeMapper;
    private JwtProperties jwtProperties;

    /**
     * 分页查询
     *
     * @param condition 分页及自定义条件
     * @return 员工分页列表
     */
    @Override
    public PageBean pageList(EmployeePageQueryDTO condition) {
        PageHelper.startPage(condition.getPage(), condition.getPageSize());
        Page<EmployeeVO> page = employeeMapper.list(condition);

        return new PageBean(page.getTotal(), page.getResult());
    }

    /**
     * 获取员工列表
     *
     * @return  所有员工
     */
    @Override
    public List<EmployeeVO> list() {
        return employeeMapper.list(null);
    }

    /**
     * 新增员工
     *
     * @param employeeDTO 员工信息
     */
    @Override
    public void add(EmployeeDTO employeeDTO) {
        Employee byUsername = employeeMapper.getByUsername(employeeDTO.getUsername());
        if (byUsername != null) {
            throw new BaseException("账号已存在,添加失败!!!");
        }

        Employee employee = new Employee();
        //对象属性拷贝
        BeanUtils.copyProperties(employeeDTO, employee);

        //设置账号的状态，默认正常状态 1表示正常 0表示锁定
        employee.setStatus(StatusConstant.ENABLE);

        //设置默认密码
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));

        employeeMapper.add(employee);
    }

    /**
     * 修改员工
     *
     * @param employeeDTO 员工信息
     */
    @Override
    public void update(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();

        //对象属性拷贝
        BeanUtils.copyProperties(employeeDTO, employee);

        employeeMapper.update(employee);
    }

    /**
     * 根据id删除员工
     *
     * @param id 要删除的员工id
     */
    @Override
    public void deleteById(Integer id) {
        employeeMapper.deleteById(id);
    }

    /**
     * 员工登录
     *
     * @param employeeLoginDTO 登录参数
     * @return 用户的jwt信息
     */
    @Override
    public EmployeeLoginVO login(EmployeeLoginDTO employeeLoginDTO) {
        Employee employee = employeeMapper.getByUsername(employeeLoginDTO.getUsername());

        if (employee == null) {
            throw new LoginFailedException(MessageConstant.ACCOUNT_NOT_FOUND);
        } else {
            String loginPassword;
            try {
                loginPassword = DigestUtils.md5DigestAsHex(employeeLoginDTO.getPassword().getBytes("utf-8"));
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("服务器出现异常");
            }
            //密码正确返回token
            if (employee.getPassword().equals(loginPassword)) {
                if (employee.getStatus() == 0) { //判断账户是否被禁用
                    throw new LoginFailedException("账户已被禁用,请联系管理员!!!");
                }

                return getEmployeeLoginInfo(employee);
            } else {
                throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
            }
        }
    }

    /**
     * 启用、禁用员工账号
     *
     * @param status 状态
     * @param id     要操作的员工id
     */
    @Override
    public void updateStatus(Integer status, Integer id) {
        employeeMapper.updateStatus(status, id);
    }

    /**
     * 修改密码
     *
     * @param passwordEditDTO 修改密码
     */
    @Override
    @SneakyThrows
    public void editPassword(PasswordEditDTO passwordEditDTO) {
        Employee employeeById = employeeMapper.getById(Math.toIntExact(passwordEditDTO.getEmpId()));

        if(!DigestUtils.md5DigestAsHex(passwordEditDTO.getOldPassword().getBytes("utf-8"))
                .equals(employeeById.getPassword())){
            throw new PasswordErrorException(MessageConstant.PASSWORD_EDIT_FAILED);
        }

        employeeMapper.updatePassword(passwordEditDTO);
    }

    /**
     * 根据id查询员工
     *
     * @param id
     * @return
     */
    @Override
    public Employee getById(Integer id) {
        return employeeMapper.getById(id);
    }

    /**
     *
     * @param employee
     * @return
     */
    private EmployeeLoginVO getEmployeeLoginInfo(Employee employee) {
        EmployeeLoginVO employeeLoginVO = new EmployeeLoginVO();

        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
        claims.put(JwtClaimsConstant.NAME, employee.getName());
        claims.put(JwtClaimsConstant.USERNAME, employee.getUsername());
        claims.put(JwtClaimsConstant.PHONE, employee.getPhone());

        String jwt = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(), jwtProperties.getAdminTtl(), claims);
        employeeLoginVO.setId(employee.getId());
        employeeLoginVO.setName(employee.getName());
        employeeLoginVO.setUserName(employee.getUsername());
        employeeLoginVO.setToken(jwt);

        return employeeLoginVO;
    }
}
